﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace 双色球随机测试
{
    public partial class FrmMain : Form
    {
        const int StartState = 1;
        const int WaitState = 2;
        const int EndState = 3;
        const bool YesChangeLblTip = true;
        const bool NoChangeLblTip = false;
        private string[] RedBallArr = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33" };
        private string[] BlueBallArr = { "01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12", "13", "14", "15", "16" };
        private List<DGVResultData> FDGVResultDataList = new List<DGVResultData>();
        private Boolean FIsEnd = false;

        public List<DGVResultData> DGVResultDataList { get => FDGVResultDataList; set => FDGVResultDataList = value; }
        public Boolean IsEnd { get => FIsEnd; set => FIsEnd = value; }

        public FrmMain()
        {
            InitializeComponent();
        }

        private void BtnInPutCount_Click(object sender, EventArgs e)
        {
            try
            {
                Int64 InPutCount = int.Parse(TxtInPutCount.Text);
                if (InPutCount <= 0)
                {
                    MessageBox.Show("错误内容:\n" + "输入次数不能小于等于0！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    return;
                }

                CalcInPutCount(InPutCount);
            }
            catch (Exception ex)
            {
                MessageBox.Show("错误内容:\n" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void CalcInPutCount(Int64 InPutCount)
        {
            string FilePath = AppDomain.CurrentDomain.BaseDirectory + "双色球随机测试.txt";
            if (File.Exists(FilePath))
            {
                File.Delete(FilePath);
            }

            if (DGVResultDataList == null)
            {
                DGVResultDataList = new List<DGVResultData>();
            }
            DGVResultDataList.Clear();
            LblRandomCount.Text = "随机次数:" + DGVResultDataList.Count.ToString();

            if (ChkIsCalcRepeat.Checked)
            {
                CalcNoRepeatCount(InPutCount);
            }
            else
            {
                CalcRepeatCount(InPutCount);
            }
        }

        public void CalcRepeatCount(Int64 InPutCount)
        {
            ChangeLblTip(StartState);

            Task CalcRepeatCountTask = new Task(() =>
            {
                Stopwatch sw = new Stopwatch();//创建Stopwatch实例  
                ChangeLblTip(WaitState);

                //*****以下是异步执行的代码*****                   
                MethodInvoker MICalcRepeatCountStart = new MethodInvoker(() =>
                {
                    BtnInPutCount.Enabled = false;
                    BtnOpenFile.Enabled = false;
                    BtnDataAnalysis.Enabled = false;
                    ChkIsCalcRepeat.Enabled = false;
                    sw.Start();//开始计时
                });
                this.BeginInvoke(MICalcRepeatCountStart);
                //*****以上是异步执行的代码*****                

                //事务列表
                List<Task<List<DGVResultData>>> TempDGVResultDataTaskList = new List<Task<List<DGVResultData>>>();

                while (InPutCount > 0)
                {
                    if (InPutCount >= 10000)
                    {

                        var task = Task<List<DGVResultData>>.Factory.StartNew(() =>
                        {
                            List<DGVResultData> TempList = new List<DGVResultData>();
                            for (int i = 0; i < 10000; i++)
                            {
                                DGVResultData TempDGVResultData = GetDGVResultData();
                                if (TempDGVResultData != null)
                                {
                                    DGVResultData TempDGVResultData2 = (from v in TempList
                                                                        where v.ResultStr == TempDGVResultData.ResultStr
                                                                        select v).SingleOrDefault();

                                    if (TempDGVResultData2 != null)
                                    {
                                        TempDGVResultData2.ResultStrCount = TempDGVResultData2.ResultStrCount + 1;
                                    }
                                    else
                                    {
                                        TempList.Add(TempDGVResultData);
                                    }
                                }
                            }
                            return TempList;
                        });
                        TempDGVResultDataTaskList.Add(task);
                        InPutCount -= 10000;
                    }
                    else
                    {
                        var task = Task<List<DGVResultData>>.Factory.StartNew(() =>
                        {
                            List<DGVResultData> TempList = new List<DGVResultData>();
                            for (int i = 0; i < InPutCount; i++)
                            {
                                DGVResultData TempDGVResultData = GetDGVResultData();
                                if (TempDGVResultData != null)
                                {
                                    DGVResultData TempDGVResultData2 = (from v in TempList
                                                                        where v.ResultStr == TempDGVResultData.ResultStr
                                                                        select v).SingleOrDefault();

                                    if (TempDGVResultData2 != null)
                                    {
                                        TempDGVResultData2.ResultStrCount = TempDGVResultData2.ResultStrCount + 1;
                                    }
                                    else
                                    {
                                        TempList.Add(TempDGVResultData);
                                    }
                                }
                            }
                            return TempList;
                        });
                        TempDGVResultDataTaskList.Add(task);
                        InPutCount = 0;
                    }
                }                

                foreach (var Item in TempDGVResultDataTaskList)
                {
                    DGVResultDataList.AddRange(Item.Result);
                    Debug.Print("当前计算用时:" + sw.ElapsedMilliseconds + "毫秒");
                    Debug.Print("当前计算用时:" + (sw.ElapsedMilliseconds / 1000) + "秒");
                    /*foreach (var ItemResultData in Item.Result)
                    {
                        DGVResultData TempDGVResultData3 = (from v in DGVResultDataList
                                                            where v.ResultStr == ItemResultData.ResultStr
                                                            select v).SingleOrDefault();
                        if (TempDGVResultData3 != null)
                        {
                            TempDGVResultData3.ResultStrCount = TempDGVResultData3.ResultStrCount + 1;
                        }
                        else
                        {
                            TempDGVResultData3 = new DGVResultData
                            {
                                ResultStr = ItemResultData.ResultStr,
                                ResultStrCount = ItemResultData.ResultStrCount,
                                RedResultStr = ItemResultData.RedResultStr,
                                BlueResultStr = ItemResultData.BlueResultStr
                            };
                            DGVResultDataList.Add(TempDGVResultData3);
                        }
                    }*/
                }

                if (DGVResultDataList.Count > 0)
                {
                    /*DGVResultDataList.Sort((a, b) =>
                    {
                        if (a.ResultStrCount > b.ResultStrCount)
                        {
                            return -1;
                        }
                        else if (a.ResultStrCount == b.ResultStrCount)
                        {
                            return 0;
                        }
                        else
                        {
                            return 1;
                        }
                    });//重新排序(次数越多越靠上) 不排序了生成时巨慢*/
                    WriteLog(DGVResultDataList);
                }

                if (ChkIsShowRTxtOpenFile.Checked)
                {
                    MethodInvoker MIChkIsShowRTxtOpenFile = new MethodInvoker(() =>
                    {
                        OpenFile(NoChangeLblTip);
                    });
                    this.BeginInvoke(MIChkIsShowRTxtOpenFile);
                }

                if (ChkIsShowDGVResult.Checked)
                {
                    if (DGVResultDataList.Count > 0)
                    {
                        DataTable DTResult = new DataTable();
                        DTResult.Columns.Add("红蓝球号", typeof(string));
                        DTResult.Columns.Add("出现次数", typeof(Int64));
                        DTResult.Columns.Add("红球号", typeof(string));
                        DTResult.Columns.Add("蓝球号", typeof(string));

                        foreach (var DGVResultDataListItem in DGVResultDataList)
                        {
                            DataRow DRResult = DTResult.NewRow();
                            DRResult["红蓝球号"] = DGVResultDataListItem.ResultStr;
                            DRResult["出现次数"] = DGVResultDataListItem.ResultStrCount;
                            DRResult["红球号"] = DGVResultDataListItem.RedResultStr;
                            DRResult["蓝球号"] = DGVResultDataListItem.BlueResultStr;
                            DTResult.Rows.Add(DRResult);
                        }
                        MethodInvoker MIDTResult = new MethodInvoker(() =>
                        {
                            DGVResult.Columns.Clear();
                            DGVResult.DataSource = DTResult;
                        });
                        this.BeginInvoke(MIDTResult);
                    }
                }

                //*****以下是异步执行的代码*****                   
                MethodInvoker MICalcRepeatCountEnd = new MethodInvoker(() =>
                {
                    BtnInPutCount.Enabled = true;
                    BtnOpenFile.Enabled = true;
                    BtnDataAnalysis.Enabled = true;
                    ChkIsCalcRepeat.Enabled = true;
                    ChangeLblTip(EndState);
                    sw.Stop();
                    Debug.Print("总随机用时:" + sw.ElapsedMilliseconds + "毫秒");
                    LblRandomCount.Text = "总结果次数:" + DGVResultDataList.Count.ToString() + ",总随机用时:" + (sw.ElapsedMilliseconds / 1000) + "秒";
                });
                this.BeginInvoke(MICalcRepeatCountEnd);
                //*****以上是异步执行的代码*****
            });
            CalcRepeatCountTask.Start();
        }

        public void CalcNoRepeatCount(Int64 InPutCount)
        {
            MessageBox.Show("错误内容:\n" + "此功能待开发！", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

        public DGVResultData GetDGVResultData()
        {            
            Int32 RedBallArrLength = RedBallArr.Length;
            Int32 BlueBallArrLength = BlueBallArr.Length;
            DGVResultData TempDGVResultData = new DGVResultData();
            List<string> RedResultStrList = new List<string>();
            byte[] buffer = Guid.NewGuid().ToByteArray();//将Guid转换为字节数组
            int seed = BitConverter.ToInt32(buffer, 0);//利用BitConvert方法把字节数组转换为整数

            Random RedRandomNum = new Random(seed);
            while (RedResultStrList.Count < 6)
            {
                string TempRedStr = RedBallArr[RedRandomNum.Next(RedBallArrLength)];
                if (!RedResultStrList.Contains(TempRedStr))
                {
                    RedResultStrList.Add(TempRedStr);
                }
            }

            string TempRedResultStr = "";
            for (Int32 J = 0; J < RedResultStrList.Count; J++)
            {
                if (TempRedResultStr == "")
                {
                    TempRedResultStr = RedResultStrList[J];
                }
                else
                {
                    TempRedResultStr = TempRedResultStr + "," + RedResultStrList[J];
                }
            }
            RedResultStrList.Clear();

            Random BlueRandomNum = new Random(seed);
            string TempBlueStr = "";
            TempBlueStr = BlueBallArr[BlueRandomNum.Next(BlueBallArrLength)];



            string TempResultStr = "";
            TempResultStr = TempRedResultStr + "," + TempBlueStr;

            TempDGVResultData.ResultStr = TempResultStr;
            TempDGVResultData.ResultStrCount = 1;
            TempDGVResultData.RedResultStr = TempRedResultStr;
            TempDGVResultData.BlueResultStr = TempBlueStr;

            return TempDGVResultData;
        }

        private void TxtInPutCount_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar != 8 && !Char.IsDigit(e.KeyChar))
            {
                e.Handled = true;
            }
        }

        public void WriteLog(List<DGVResultData> DGVResultDataList)
        {
            try
            {
                if ((DGVResultDataList != null) & (DGVResultDataList.Count > 0))
                {
                    string FilePath = AppDomain.CurrentDomain.BaseDirectory + "双色球随机测试.txt";

                    foreach (var DGVResultDataListItem in DGVResultDataList)
                    {
                        string TempStr = "";
                        TempStr = TempStr + "红蓝球号:" + DGVResultDataListItem.ResultStr + ";";
                        TempStr = TempStr + "出现次数:" + DGVResultDataListItem.ResultStrCount + ";";
                        TempStr = TempStr + "红球号:" + DGVResultDataListItem.RedResultStr + ";";
                        TempStr = TempStr + "蓝球号:" + DGVResultDataListItem.BlueResultStr + ";";

                        StreamWriter sw = new StreamWriter(FilePath, true);
                        sw.WriteLine(TempStr);
                        sw.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("错误内容:\n" + ex.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void BtnOpenFile_Click(object sender, EventArgs e)
        {
            OpenFile(YesChangeLblTip);
        }
        public void OpenFile(Boolean IsChangeLblTip)
        {
            string FilePath = AppDomain.CurrentDomain.BaseDirectory + "双色球随机测试.txt";
            if (File.Exists(FilePath))
            {
                if (IsChangeLblTip)
                {
                    ChangeLblTip(StartState);
                }

                Task OpenFileTask = new Task(() =>
                {
                    //*****以下是异步执行的代码*****                   
                    MethodInvoker MIStart = new MethodInvoker(() =>
                    {
                        BtnInPutCount.Enabled = false;
                        BtnOpenFile.Enabled = false;
                        BtnDataAnalysis.Enabled = false;
                        RTxtOpenFile.Clear();
                    });
                    this.BeginInvoke(MIStart);
                    //*****以上是异步执行的代码*****

                    if (IsChangeLblTip)
                    {
                        ChangeLblTip(WaitState);
                    }

                    string TempRTxtOpenFileStr = string.Empty;
                    using (StreamReader sr = new StreamReader(FilePath))
                    {
                        string line;
                        // 从文件读取并显示行，直到文件的末尾 
                        while ((line = sr.ReadLine()) != null)
                        {
                            TempRTxtOpenFileStr += line + "\n";
                        }
                    }

                    //*****以下是异步执行的代码*****                   
                    MethodInvoker MIEnd = new MethodInvoker(() =>
                    {
                        RTxtOpenFile.Text = TempRTxtOpenFileStr;
                        BtnOpenFile.Enabled = true;
                        BtnInPutCount.Enabled = true;
                        BtnDataAnalysis.Enabled = true;
                        if (IsChangeLblTip)
                        {
                            ChangeLblTip(EndState);
                        }
                    });
                    this.BeginInvoke(MIEnd);
                    //*****以上是异步执行的代码*****
                });
                OpenFileTask.Start();
            }
            else
            {
                MessageBox.Show("错误内容:\n" + "未找到文件!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        public void ChangeLblTip(Int32 LblTipState)
        {
            switch (LblTipState)
            {
                case StartState:
                    IsEnd = false;
                    LblTip.Text = "开始计算中";
                    break;
                case WaitState:
                    Task WaitStateTask = new Task(() =>
                    {                        
                        while (!IsEnd)
                        {
                            Thread.Sleep(50);
                            MethodInvoker MIWaitStateStart = new MethodInvoker(() =>
                            {
                                LblTip.Text = "正在计算中.";
                            });
                            this.BeginInvoke(MIWaitStateStart);
                            Thread.Sleep(50);
                            MethodInvoker MIWaitStateWait = new MethodInvoker(() =>
                            {
                                LblTip.Text = "正在计算中..";
                            });
                            this.BeginInvoke(MIWaitStateWait);
                            Thread.Sleep(50);
                            MethodInvoker MIWaitStateEnd = new MethodInvoker(() =>
                            {
                                LblTip.Text = "正在计算中...";
                            });
                            this.BeginInvoke(MIWaitStateEnd);
                        }
                    });
                    WaitStateTask.Start();
                    break;
                case EndState:
                    IsEnd = true;
                    Task EndStateTask = new Task(() =>
                    {
                        Thread.Sleep(1500);
                        MethodInvoker MIEndState = new MethodInvoker(() =>
                        {
                            LblTip.Text = "计算已完成";
                        });
                        this.BeginInvoke(MIEndState);
                    });
                    EndStateTask.Start();

                    break;
            }
        }

        private void BtnDataAnalysis_Click(object sender, EventArgs e)
        {
            if ((DGVResultDataList != null) & (DGVResultDataList.Count > 0))
            {
                Stopwatch sw = new Stopwatch();//创建Stopwatch实例  
                ChangeLblTip(StartState);
                Task BtnDataAnalysisTask = new Task(() =>
                {                                     
                    MethodInvoker MIStart = new MethodInvoker(() =>
                    {
                        BtnInPutCount.Enabled = false;
                        BtnOpenFile.Enabled = false;
                        BtnDataAnalysis.Enabled = false;
                        RTxtOpenFile.Clear();                        
                        sw.Start();//开始计时
                    });
                    this.BeginInvoke(MIStart);

                        ChangeLblTip(WaitState);
                    List<DGVResultData> TempDGVResultDataList = new List<DGVResultData>();

                    foreach (var Item in DGVResultDataList)
                    {
                        DGVResultData TempDGVResultData = (from v in TempDGVResultDataList
                                                           where v.ResultStr == Item.ResultStr
                                                           select v).SingleOrDefault();

                        if (TempDGVResultData != null)
                        {
                            TempDGVResultData.ResultStrCount = TempDGVResultData.ResultStrCount + 1;
                        }
                        else
                        {
                            TempDGVResultData = new DGVResultData { ResultStr = Item.ResultStr, ResultStrCount = Item.ResultStrCount, RedResultStr = Item.RedResultStr, BlueResultStr = Item.BlueResultStr };
                            TempDGVResultDataList.Add(TempDGVResultData);
                        }
                    }

                    TempDGVResultDataList.Sort((a, b) =>
                    {
                        if (a.ResultStrCount > b.ResultStrCount)
                        {
                            return -1;
                        }
                        else if (a.ResultStrCount == b.ResultStrCount)
                        {
                            return 0;
                        }
                        else
                        {
                            return 1;
                        }
                    });//重新排序(次数越多越靠上)

                    string TempRTxtOpenFileStr = string.Empty;
                    foreach (var Item in TempDGVResultDataList)
                    {
                        string TempStr = "";
                        TempStr = TempStr + "红蓝球号:" + Item.ResultStr + ";";
                        TempStr = TempStr + "出现次数:" + Item.ResultStrCount + ";";
                        TempStr = TempStr + "红球号:" + Item.RedResultStr + ";";
                        TempStr = TempStr + "蓝球号:" + Item.BlueResultStr + ";";
                        TempRTxtOpenFileStr += TempStr + "\n";                      
                    }

                    MethodInvoker MIEnd = new MethodInvoker(() =>
                    {                       
                        BtnOpenFile.Enabled = true;
                        BtnInPutCount.Enabled = true;
                        BtnDataAnalysis.Enabled = true;
                        RTxtOpenFile.AppendText(TempRTxtOpenFileStr);
                        ChangeLblTip(EndState);
                        sw.Stop();
                        Debug.Print("总解析用时:" + sw.ElapsedMilliseconds + "毫秒");
                        Debug.Print("总解析用时:" + (sw.ElapsedMilliseconds / 1000) + "秒");
                    });
                    this.BeginInvoke(MIEnd);
                });
                BtnDataAnalysisTask.Start();
            }
        }
    }
}

public class DGVResultData
{
    public string ResultStr { get; set; }
    public Int64 ResultStrCount { get; set; }
    public string RedResultStr { get; set; }
    public string BlueResultStr { get; set; }
}